import { IpcMessageEvent, ipcRenderer as ipc} from "electron";
import * as fs from "fs";
import * as readline from "readline";
import { IKey, KeyBox} from "./KeyBox";
import { KeyEditor } from "./KeyEditor";
import { MainPasswordWindow } from "./MainPasswordWindow";

export class KeyListPane {
    private keyBox: KeyBox = null;
    private loginDlg: Isc.LoginDialog;
    private grid: Isc.ListGrid;
    private statusLabel: Isc.Label;

    constructor( keyBox: KeyBox) {
        this.keyBox = keyBox;
    }

    public showKeyTables( keyBox?: KeyBox) {
        if ( keyBox != null) {
            this.keyBox = keyBox;
        }

        this.loginDlg = isc.LoginDialog.create({
            formFields: [
                {
                    name: "error",
                    type: "blurb",
                    value: "密码错误，请重新输入！",
                    visible: false,
                },
                {
                    keyPress: (item: Isc.FormItem, form: Isc.DynamicForm, keyName: string, characterValue: number) => {
                        if (keyName === "Enter") {
                            this.checkPassword( form, item);
                            return false;
                        }
                        return true;
                    },
                    name: "usernameItem",
                    required: true,
                    title: "密码",
                    type: "password",
                    width: 250,
                    wrapTitle: false,
                },
                {
                    click: this.checkPassword,
                    name: "confirmBtn",
                    title: "确认",
                    type: "button",
                },
            ],
        });

        this.grid = isc.ListGrid.create({
            alternateRecordStyles: true,
            dataSource: this.keyBox.getDataSource(),
            doubleClick: this.editSelectKey,
            filterOnKeypress: true,
            selectionChanged: this.selectionChanged,
            selectionType: "single",
            showFilterEditor: true,
        });

        const modifyMainKeyBtn = isc.ToolStripButton.create({
            ID: "modifyMainKey",
            click: this.modifyMainKey,
            icon: "[SKIN]/actions/edit.png",
            title: "修改主密码",
        });
        const createKeyBtn = isc.ToolStripButton.create({
            ID: "printButton",
            click: this.createKeyAction,
            icon: "[SKIN]/actions/plus.png",
            title: "创建新密码",
        });
        const delSelectKeyBtn = isc.ToolStripButton.create({
            ID: "delSelectKey",
            click: this.delSelectKeyAction,
            icon: "[SKIN]/actions/remove.png",
            title: "删除选中密码",
        });
        const exportKeyBtn = isc.ToolStripButton.create({
            ID: "exportKey",
            click: this.exportKeysAction,
            icon: "[SKIN]/actions/sort_descending.png",
            title: "导出密码",
        });
        const importKeyBtn = isc.ToolStripButton.create({
            ID: "importKey",
            click: this.importKeysAction,
            icon: "[SKIN]/actions/sort_ascending.png",
            title: "导入密码",
        });

        const toolstrip = isc.ToolStrip.create({
            height: "35",
            members: [ isc.ToolStripSeparator.create(),
                modifyMainKeyBtn, exportKeyBtn, importKeyBtn,
                isc.ToolStripSeparator.create(),
                createKeyBtn, delSelectKeyBtn],
            width: "100%",
        });

        const btnsLayout = isc.HLayout.create({
            align: "center",
            height: "35",
            members: [ toolstrip],
            width: "100%",
        });

        this.statusLabel = isc.Label.create({
            contents: "选中查看密码，双击编辑。",
            height: 35,
        });

        // Layouts
        const gridLayout = isc.HLayout.create({
            align: "center",
            height: "*",
            members: [ this.grid],
            width: "100%",
        });

        const layout = isc.VLayout.create({
            align: "center",
            height: "100%",
            members: [btnsLayout, gridLayout, this.statusLabel],
            padding: 5,
            width: "100%",
        });
    }

    private importKeysAction = () => {
        isc.logWarn( "Import key clicked.");
        ipc.once( "selected-file", ( event: IpcMessageEvent, path: string[]) => {
            if ( path.length > 0) {
                isc.logEcho( path, "You select ");
                const rl = readline.createInterface({
                    input: fs.createReadStream( path[0]),
                });
                let lineCount = 0;
                let keyCount = 0;
                rl.on( "line", (line: string) => {
                    try {
                        const ikey = JSON.parse( line) as IKey;
                        isc.logEcho( ikey, "IKey is:");
                        ikey.password = this.keyBox.encrypt( ikey.password);
                        this.keyBox.saveKey( ikey, false, false);
                        keyCount++;
                    } catch ( e) {
                        // do nothing.
                    }
                    lineCount++;
                });
                rl.on( "close", () => {
                    rl.close();
                    isc.say( `共导入 ${lineCount} 行，其中有 ${keyCount} 个密钥。`);
                    this.keyBox.reloadKeys();
                });
            }
        });
        ipc.send( "open-file-dialog");
        return false;
    }
    private exportKeysAction = () => {
        isc.ask( "警告：导出的密码是明文未加密的，一定要妥善保管。请确定是否需要导出？", ( value: boolean) => {
            if ( value) {
                this.keyBox.exportKeys();
                isc.say( "已完成导出，文件在 data/exports 目录下，请妥善保管，加密后保存。");
            }
        });
        return false;
    }
    private modifyMainKey = () => {
        const win = new MainPasswordWindow( this);
        win.showCreateMainPasswordWindow( this.keyBox);
        return false;
    }

    private selectionChanged = ( record: Isc.Record, state: boolean) => {
        if ( state) {
            const key = record as IKey;
            const realPwd = this.keyBox.decrypt( key.password);
            this.statusLabel.setContents( "选中查看密码，双击编辑。当前选中密码已拷贝至剪贴板：" + realPwd);
            const copyToClipboard = (txt: string) => {
                const listener = (e: ClipboardEvent) => {
                    e.clipboardData.setData( "text/plain", txt);
                    e.preventDefault();
                    document.removeEventListener( "copy", listener);
                };
                document.addEventListener( "copy", listener);
                document.execCommand( "copy");
            };
            copyToClipboard( realPwd);
        }
    }
    private delSelectKeyAction = () => {
        const key = this.grid.getSelectedRecord() as IKey;
        if ( key == null) {
            return false;
        }
        isc.confirm( "删除选中的密码：" + key.url + "？", ( value: boolean) => {
            if ( value) {
                this.keyBox.removeKey( key);
            }
        });
        return false;
    }
    private editSelectKey = () => {
        const key = this.grid.getSelectedRecord() as IKey;
        const ke = new KeyEditor( this.keyBox, key);
        ke.show();
        return false;
    }
    private checkPassword = ( form2: Isc.DynamicForm, item: Isc.FormItem): boolean => {
        form2.validate();
        if ( this.keyBox.checkPassword( form2.getValue( "usernameItem"))) {
            this.loginDlg.close();
            this.grid.fetchData( null, () => {
                this.grid.deselectAllRecords();
            });
        } else {
            form2.getItem( "error").show();
        }
        return false;
    }
    private createKeyAction = () => {
        const ke = new KeyEditor( this.keyBox);
        ke.show();
        return false;
    }
}
